/****************************************************************************
 * Filename : video-text.c
 * Date     : 14-11-2010
 *
 * Copyright (C) 2010  João Fernandes, Renato Rodrigues
 *
 * This file is part of Bubblecraft.
 *
 * Bubblecraft is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Bubblecraft is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ****************************************************************************/

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <go32.h>
#include <sys/farptr.h>

#include "video-text.h"



inline bool_t isValidCoordinate(int x, int y) {
  return (x >= 0 && x < WIDTH && y >= 0 && y < HEIGHT);
}

bool_t printCharAt(char ch, int x, int y, byte_t attributes) {
  if (!isValidCoordinate(x, y))
    return false;
  
  dword_t base    = VIDEO_TEXT,
          offset  = (WIDTH * y + x) * 2;

  _farsetsel(_dos_ds);
  _farnspokeb(base + offset, ch);
  _farnspokeb(base + offset + 1, attributes);
  
  return true;
}

void fillScreen(char ch, byte_t attributes) {
  int x, y;
  
  for (y = 0; y < HEIGHT; ++y)
    for (x = 0; x < WIDTH; ++x)
      printCharAt(ch, x, y, attributes);
}

void clearScreen() {
  fillScreen(0xFF, WHITE);
}

bool_t printStringAt(char *str, int x, int y, byte_t attributes) {
  if (!isValidCoordinate(x, y))
    return false;
  
  unsigned int strSize = 0,
               screenCharsLeft = 0,
               i = 0;

  while (str[strSize] != 0)
    ++strSize;
    
  screenCharsLeft = WIDTH - x;
  for (i = y + 1; i < HEIGHT; ++i) {
    screenCharsLeft += WIDTH;
    if (screenCharsLeft >= strSize)
      break;
  }
  
  if (strSize > screenCharsLeft)
    return false;
  
  i = 0;
  
  while (str[i] != 0) {
    if (x == WIDTH) {
      x = 0;
      ++y;
    }
    
    printCharAt(str[i++], x++, y, attributes);
  }

  return true;
}

bool_t printIntAt(int num, int x, int y, byte_t attributes) {  
  if (!isValidCoordinate(x, y))
    return false;
    
  char str[10];
  sprintf(str, "%d", num);
  
  return printStringAt(str, x, y, attributes);
}

bool_t drawFrame(char *title, byte_t attributes, int x, int y, int width, int height) {
  
  /* Validação do tamanho da frame */
  if (WIDTH - x < width || HEIGHT - y < height)
    return false;
    
  /* Verificar se o titulo cabe na moldura */
  int titleSize = 0;
  
  while(title[titleSize] != 0)
    ++titleSize;
  
  if(titleSize > width - 6)
    return false;  

  unsigned int finalY = y + height -1,
               finalX = x + width - 1;
  
  /*
   * Desenho dos limites da frame
   */
  /* Canto superior esquerdo */
  if(!printCharAt(0xC9, x, y, attributes))
    return false;
  /* Canto superior direito */
  if(!printCharAt(0xBB, finalX, y, attributes)) 
    return false;		
  /* Canto inferior esquerdo */
  if(!printCharAt(0xC8, x, finalY, attributes)) 
    return false;		
  /* Canto inferior direito */
  if(!printCharAt(0xBC, finalX, finalY, attributes)) 
    return false;	
  
  int i;
  for(i = x + 1; i < finalX; ++i) {
    /* Margem superior */
    printCharAt(0xCD, i, y, attributes);
    /* Margem inferior */
    printCharAt(0xCD, i, finalY, attributes);						
  }
  
  for (i = y + 1; i < finalY; i++) {
    /* Margem esquerda */
    printCharAt(0xBA, x, i, attributes);
    /* Margem direita	*/
    printCharAt(0xBA, finalX, i, attributes);					
  }
  
  /* Título */
  if (titleSize != 0) {
    char spacerAttributes;
    spacerAttributes = (attributes >> 4) | (attributes & 0x70);
    printCharAt(0xDB, x + 2, y, spacerAttributes);
    printStringAt(title, x + 3, y, attributes);
    printCharAt(0xDB, x + titleSize + 3, y, spacerAttributes);
  }
  
  return true;
}
